//
//  LGSSwitch.m
//  LogicSim
//
//  Created by Jeremy Pereira on 04/04/2012.
//  Copyright (c) 2012 Jeremy Pereira. All rights reserved.
//

#import "LGSSwitch.h"
#import "LGSEdge.h"
#import "LGSName.h"

enum
{
    SELECTOR_INPUT = 2
};


@implementation LGSSwitch

-(void) evaluateAffectedNodes: (NSMutableOrderedSet*) affectedNodes;
{
    bool selectValue = [[self input: [[self class] selectName]] value];
    bool result = false;
    if (!selectValue)
    {
        result = [[self input: [[self class] aName]] value];
    }
    else
    {
        result = [[self input: [[self class] bName]] value];
    }
    
    for (LGSEdge* edge in [self outputsForName:[[self class] outputName]])
    {
        [edge setValue: result affectedNodes: affectedNodes];
    }
}

-(TimeTick) gateDelay
{
    return 1;
}


+(NSArray*) defaultInputNames
{
    return @[[LGSName nameWithConnectionString: @"a"],
             [LGSName nameWithConnectionString: @"b"],
             [LGSName nameWithConnectionString: @"select"]];
}

+(NSArray*) defaultOutputNames
{
    return @[[LGSName nameWithConnectionString: @"out"]];
}

+(LGSName*) selectName
{
    static LGSName* name = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken,
    ^{
        name = [[LGSName alloc] initWithNodePart: nil
                                  connectionPart: @"select"
                                       nodeIndex: LGS_NAME_NO_INDEX
                                 connectionIndex: LGS_NAME_NO_INDEX];
    });
    return name;
}

+(LGSName*) aName
{
    static LGSName* name = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken,
      ^{
          name = [[LGSName alloc] initWithNodePart: nil
                                    connectionPart: @"a"
                                         nodeIndex: LGS_NAME_NO_INDEX
                                   connectionIndex: LGS_NAME_NO_INDEX];
      });
    return name;
}

+(LGSName*) bName
{
    static LGSName* name = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken,
      ^{
          name = [[LGSName alloc] initWithNodePart: nil
                                    connectionPart: @"b"
                                         nodeIndex: LGS_NAME_NO_INDEX
                                   connectionIndex: LGS_NAME_NO_INDEX];
      });
    return name;
}

+(LGSName*) outputName
{
    static LGSName* name = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken,
      ^{
          name = [[LGSName alloc] initWithNodePart: nil
                                    connectionPart: @"out"
                                         nodeIndex: LGS_NAME_NO_INDEX
                                   connectionIndex: LGS_NAME_NO_INDEX];
      });
    return name;
}



@end
